﻿define([
    "dojo/_base/connect",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/_base/Deferred",

    "dijit/focus",
    "dijit/_CssStateMixin",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",

     "dijit/form/ValidationTextBox",

// epi.cms
    "epi-cms/legacy/LegacyDialogPopup",
    "epi-cms/widget/_HasChildDialogMixin",
    "epi/epi",
    "epi/dependency",
    "epi/routes",
    "epi/shell/widget/_ValueRequiredMixin",

    "dojo/text!./VideoUrlSelector.html"

    , "xstyle/css!./VideoUrlSelector.css"
],
function (
    connect,
    declare,
    lang,
    Deferred,

    focusManager,
    _CssStateMixin,
    _Widget,
    _TemplatedMixin,
    _WidgetsInTemplateMixin,
    ValidationTextBox,

    LegacyDialogPopup,
    _HasChildDialogMixin,
    epi,
    dependency,
    routes,
    _ValueRequiredMixin,

    template
) {

    return declare("ow-epi-videoProperty.widgets.VideoUrlSelector", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin, _HasChildDialogMixin], {

        templateString: template,

        helptext: "Select a video",

        intermediateChanges: false,

        baseClass: 'video-selector',

        value: null,

        cachedThumbnailsUrls: [],

        throttle: function (fn, delay) {
            var timer = null;
            return function () {
                var context = this, args = arguments;
                clearTimeout(timer);
                timer = setTimeout(function () {
                    fn.apply(context, args);
                }, delay);
            };
        },

        debounce: function (func, threshold, execAsap) {

            var timeout;

            return function debounced() {
                var obj = this, args = arguments;
                function delayed() {
                    if (!execAsap)
                        func.apply(obj, args);
                    timeout = null;
                };

                if (timeout)
                    clearTimeout(timeout);
                else if (execAsap)
                    func.apply(obj, args);

                timeout = setTimeout(delayed, threshold || 100);
            };

        },

        postMixInProperties: function () {
            this.inherited(arguments);
            if (this.selectedVideoUrl && this.selectedVideoUrl.key) {
                this.cachedThumbnailsUrls[this.selectedVideoUrl.key] = this.selectedVideoUrl.value;
            }
        },

        _onPaste: function (event) {
            setTimeout(function () {
                dijit.byId(event.target.id).onBlur();
            }, 0);
        },

        postCreate: function () {
            this.inherited(arguments);
            this.videoUrlTextBox.set("intermediateChanges", this.intermediateChanges);
            this.connect(this.videoUrlTextBox, "onChange", this.throttle(function (value) {
                this._onTextBoxChanged(value);
            }, 1000));
            this.connect(this.videoUrlTextBox, "onBlur", this._onTextBlur);
            this.connect(this.clearButton, "onClick", this._clearValue);

            //localization
            this.emptyMessageText.innerText = this.emptyMessage;
            this.clearButton.setLabel(this.clearButtonText);

            this.videoUrlTextBox.domNode.onpaste = this._onPaste;
            this.loadThumbnail("");
        },

        _onTextBoxChanged: function (value) {
            this.loadThumbnail(value);
            this._setValue(value);

        },

        _setValidatedValue: function (value) {
            this.videoUrlTextBox.focus();
            this.videoUrlTextBox.validator = function () { return value; };
            this.videoUrlTextBox.validate();
        },

        _onTextBlur: function (value) {

            this._setValidatedValue(true);

            var url = this.videoUrlTextBox.get("value");
            if (url) {
                this.loadThumbnail(url);
                this._setValue(url);
            }

        },

        _clearValue: function () {
            this._setValue("");
            this.loadThumbnail("");
        },

        _setValue: function (value) {

            this._setValueAttr(value);
        },

        isValid: function () {
            return true;
        },

        _setValueAttr: function (value) {

            this.videoUrlTextBox.set("value", value);
            this._set("value", value);
        }

        , _setReadOnlyAttr: function (value) {
            this._set("readOnly", value);
            this.videoUrlTextBox.set("readOnly", value);
            this.clearButton.set("readOnly", value);
        },

        _setStateAttr: function (value) {
            this._set("state", value);
        },


        _setIntermediateChangesAttr: function (value) {
            this._set("intermediateChanges", value);
        }

        , destroy: function () {

            if (this._dialog) {
                this._dialog.destroyRecursive();
                delete this._dialog;
            }
            this.inherited(arguments);
        }

        , loadThumbnail: function (videoUrl) {
            if (!videoUrl) {
                this.thumbnail.src = "#";
                this.thumbnail.style.display = "none";
                this._setValidatedValue(true);

                return;
            }

            if (this.cachedThumbnailsUrls[videoUrl]) {
                this.thumbnail.src = this.cachedThumbnailsUrls[videoUrl];
                this._setValidatedValue(true);
                this.thumbnail.style.display = "block";
                return;
            }

            var self = this;
            dojo.xhrGet({
                url: self.videoInfoControllerUrl + "/GetVideoMetaData",
                handleAs: "json",
                content: {
                    videoUrl: videoUrl
                },
                load: function (result) {
                    if (result && result.Thumbnails) {

                        var thumbnails = result.Thumbnails;
                        var selectedThumbnailIndex = 0;


                        function sortfunction(a, b) {
                            if (a.Width > b.width) {
                                return -1;
                            }
                            else if (a.Width > b.width) {
                                return 1;
                            }
                            return 0;
                        }

                        thumbnails.sort(sortfunction);

                        for (var i = 0; i < thumbnails.length - 1; i += 1) {
                            var thumbnail = thumbnails[i];
                            var nextThumbnail = thumbnails[i + 1];

                            var tWidth = thumbnail.Width - 400;
                            var nWidth = nextThumbnail.Width - 400;
                            var sWidth = thumbnails[selectedThumbnailIndex].Width - 400;

                            var tWidthAbs = Math.abs(tWidth);
                            var nWidthAbs = Math.abs(nWidth);
                            var sWidthAbs = Math.abs(sWidth);

                            if (tWidthAbs <= nWidthAbs) {
                                if (tWidthAbs <= sWidthAbs && tWidth > 0) {
                                    selectedThumbnailIndex = i;
                                }
                                else if (nWidthAbs <= sWidthAbs && nWidth > 0) {
                                    selectedThumbnailIndex = i + 1;
                                }
                            } else {
                                if (nWidthAbs <= sWidthAbs && nWidth > 0) {
                                    selectedThumbnailIndex = i + 1;
                                }
                            }
                        }

                        self.cachedThumbnailsUrls[videoUrl] = result.Thumbnails[selectedThumbnailIndex].Url;
                        self.thumbnail.src = result.Thumbnails[selectedThumbnailIndex].Url;
                        self._setValidatedValue(true);
                        self.thumbnail.style.display = "block";

                    } else {
                        self.thumbnail.src = "#";
                        self.thumbnail.style.display = "none";
                        self._setValidatedValue(false);
                    }
                }
            });
        }

        , _previewVideo: function () {
            if (this.value === null || this.value === undefined) {
                return;
            }

            if (!this._dialog) {
                var params = this._getLegacyDialogParameters();

                var legacyDialogUrl = this._getLegacyDialogUrl();
                this._dialog = new LegacyDialogPopup(lang.mixin(params, {
                    url: legacyDialogUrl,
                    closeIconVisible: true
                }));

                this.connect(this._dialog, "onCallback", this._onDialogCallback);
                this.connect(this._dialog, 'onHide', this._onDialogHide);
            }

            this.isShowingChildDialog = true;

            this._dialog.show();
        }

        , _onDialogCallback: function (value) {

            return;
        }

        , _getLegacyDialogUrl: function () {
            var params = {

            };

            if (this.value) {
                params.videoUrl = encodeURIComponent(this.value);
            }

            return routes.getActionPath(params, this.videoPreviewDialogUrl);
        }

        , _getLegacyDialogParameters: function () {
            return {
                autoFit: false,
                features: {
                    width: 800,
                    height: 400
                }
            };
        }

        , _onDialogHide: function () {
            this.isShowingChildDialog = false;

            this._dialog.destroyRecursive();
            delete this._dialog;
        }
    });
});